package com.shujia.day17;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class Demo02GetClazzInfo {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, InvocationTargetException {
        /*
            TODO
                通过反射获取构造方法并使用
         */
        // TODO 1.先获取当前Student类的类对象
        Class<Stu> studentClass = Stu.class;  // 包含了当前类的一些信息
        // TODO 2.根据class文件中的信息，构建一个类的对象
        //  newInstance 可以根据Class文件创建一个对象 该方法属于 Class
        //   每次调用 newInstance 方法都会创建一个新的对象
//        Stu student1 = studentClass.newInstance();
//        System.out.println(student1);
//        Stu student2 = studentClass.newInstance();
//        System.out.println(student2);

        /*
            TODO： 思考 => newInstance方法如何构建出对象的？
                        对象的构建都是通过构造方法 给定的   newInstance 实际上是调用了 Student的无参构造方法
                    当将Stu中的无参构造去除会报错
                        Caused by: java.lang.NoSuchMethodException: com.shujia.day17.Stu.<init>()
                    说明就是调用无参构造

         */

        /*
            TODO:当无参构造方法是私有的情况下：
                 IllegalAccessException: Class com.shujia.day17.Demo02GetClazzInfo can not access a member
                    of class com.shujia.day17.Stu with modifiers "private"
                 权限不足
                 通过 getDeclaredConstructors 方法可以获取到所有权限的构造方法
                 通过 setAccessible(true) 方法可以去设置当前的权限
                 通过 newInstance方法 调用构造方法

         */

        // getConstructors 可以获取到所有的构造方法
        Constructor<?>[] constructors = studentClass.getConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }

        //
        Constructor<?>[] declaredConstructors = studentClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }

        // 通过取出下标为0的构造方法
        Constructor<?> declaredConstructor = declaredConstructors[0];
        declaredConstructor.setAccessible(true);

        Stu stu = (Stu)declaredConstructor.newInstance();
        System.out.println(stu);

        // TODO 通过反射的方式获取有参构造
        Constructor<?> declaredConstructor2 = declaredConstructors[1];
        Stu stu2 =  (Stu)declaredConstructor2.newInstance("张三", 18);
        System.out.println(stu2.name);

    }
}
